#####################################################################
# Product:      KnowledgeEngine (Plone Edition)
#
# File:         LinkReport.py
#
# Copyright:    Copyright (c) 2005, Faulkner Technologies
#
# Author:       Brian Oliver
#
# Description:  A LinkReport is a simple Component that permits capturing
#               of text imformation during the process of an assessment.
#####################################################################

#####################################################################
## Knowledge Engine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.Core import *
from Products.KnowledgeEngine.Component import Component, ComponentInfo
from Products.KnowledgeEngine.Assessible import Assessible
from Products.KnowledgeEngine.AssessmentComponentState import AssessmentComponentState
from Products.KnowledgeEngine.AssessmentComponentValueTypes import *
from Products.KnowledgeEngine.Exportable import Exportable
from Products.KnowledgeEngine.KERLExtensions import KERLExtensions
from Products.KnowledgeEngine.PropertyDefinition import *
from Products.KnowledgeEngine.PropertyTypes import *
from Products.KnowledgeEngine.PropertyFormats import *
from Products.KnowledgeEngine.PropertyStructures import *
from Products.KnowledgeEngine.KERFProcessor import *
from Products.KnowledgeEngine.KERLProcessor import InvalidKerlOperator

#####################################################################
## Zope Library Imports
from Globals import DTMLFile
from App.ImageFile import ImageFile

#####################################################################
## Python Library Imports
# (none)

#####################################################################
## LinkReportInfo Class Definition
class LinkReportInfo(ComponentInfo):
    """
        Defines the class info methods, defining information about
        the class without needing an instance of the class
    """

    #---------------------------------------------------------------#
    
    def getClassName(self):
        """
            Return the class name
        """
        
        return 'LinkReport'

    #---------------------------------------------------------------#

    def getDisplayName(self):
        """
            Return a friendly name for the class instances
            (this is used for displaying in lists etc)
        """
    
        return "Link Report"
        
    #---------------------------------------------------------------#

    def getIdentityType(self):
        """
            Return the identity type.  
        """
        
        return "linkreport"
        
    #---------------------------------------------------------------#
    
    def getClassIcon(self):
        """
            Return the appropriate icon file for the class.
        """
        
        return ImageFile('skins/LinkReport_icon.gif', globals())

    #---------------------------------------------------------------#

    def isInstanceOf(self, className):
        """
            Returns if the class is an instance of the specified
            className, or implements the interface specified 
            by the className
        """

        return className in ("LinkReport", 'Assessible', 'Exportable') or ComponentInfo.isInstanceOf(self, className)
    
    #---------------------------------------------------------------#

    def onConfigureProperties(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific properties using the PropertyReflection interface.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """

     

        #initialise the super-class properties for reflection
        ComponentInfo.onConfigureProperties(self)
        
        self.addPropertyDefinition(PropertyDefinition(
            identity="displayIncoming", 
            displayName="Display Incoming Links", 
            description="", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_NATIVE            
        ))
        
        self.addPropertyDefinition(PropertyDefinition(
            identity="displayOutgoing", 
            displayName="Display Outgoing Links", 
            description="", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_NATIVE            
        ))   
        
        self.addPropertyDefinition(PropertyDefinition(
            identity="showInReport", 
            displayName="Show in reports", 
            description="", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_NATIVE            
        ))  
        
        self.addPropertyDefinition(PropertyDefinition(
            identity="showInAssessment", 
            displayName="Show in assessments", 
            description="", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_NATIVE            
        ))        
     
        self.addPropertyDefinition(PropertyDefinition(
            identity="displayFields", 
            displayName="Display Fields", 
            description="Enter the componentIdentities you want to show up in the display table (format: compID,compID|column title)", 
            propertyType=pt_STRING, 
            propertyFormat=pf_TEXT_MULTILINE            
        ))
           
        self.addPropertyDefinition(PropertyDefinition(
            identity="showModel", 
            displayName="Show Model", 
            description="", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_NATIVE            
        ))
                           
        self.addPropertyDefinition(PropertyDefinition(
            identity="showDate", 
            displayName="Show Date", 
            description="", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_NATIVE            
        ))
                                                      
        self.addPropertyDefinition(PropertyDefinition(
            identity="showAuthor", 
            displayName="Show Author", 
            description="", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_NATIVE            
        ))                                              
            
            
        self.addPropertyDefinition(PropertyDefinition(
            identity="showReports", 
            displayName="Show Reports", 
            description="", 
            propertyType=pt_BOOLEAN, 
            propertyFormat=pf_NATIVE            
        ))
#    

    #---------------------------------------------------------------#

#####################################################################
## LinkReport Class Definition
class LinkReport(Component, Assessible, KERLExtensions, Exportable):
    """
        Defines a simple component to represent one or more lines of 
        text entered during an assessment.
    """

    #---------------------------------------------------------------#

    #TRANSIENT: a ClassInfo implementation instance to provide info about this class
    _CLASSINFO = LinkReportInfo()
    
    #---------------------------------------------------------------#

    # DTML Methods
    index_html = DTMLFile('dtml/index_html', globals())
    simplereport_html = DTMLFile('dtml/simplereport_html', globals())

    #---------------------------------------------------------------#

    def __init__(self, id, identity):
        "Constructor for the LinkReport"        

        Component.__init__(self, id, identity)

    #---------------------------------------------------------------#

   
        
    def getAssessmentValueType(self):
        """
            ABSTRACT: Returns the type of the value that is to be stored
            for this component when it's assessment state is persisted.
            
            NOTE 1: See AssessmentComponentValueTypes for a list of defined contants       
            NOTE 2: This method MUST be overriden in the implementing
            class to specify the correct type for value persistence
            
            RETURN TYPE: String
        """
        
        #textbox assessment values are strings
        return st_STRING
        
    #---------------------------------------------------------------#
        
    def getDefaultAssessmentState(self, assessment):
        """
            ABSTRACT: Constructs and returns a suitable 'default' 
            AssessmentComponentState for the provided Assessment
            instance.

            NOTE: This method MUST be overriden in the implementing
            class to provide a suitable default value for the component
            
            RETURN TYPE: AssessmentComponentState
        """
        
        return AssessmentComponentState(assessment.getIdentity(), assessment.getModelIdentity(), self.getIdentity(), self.getAssessmentValueType(), self.getDefaultValue(), revision=assessment.getRevision())
            
    #---------------------------------------------------------------#

    def updateAssessmentState(self, assessment, formValue, skipMandatory=False):
        """
            ABSTRACT: Updates the specified assessment using
            the provided HTTP REQUEST formValue.
            
            NOTE: This method MUST be overriden in the implementing
            class to suitably update the component state
        """
                       
            
        pass
        
            
    #---------------------------------------------------------------#
    # END: Assessible Implementation                                #
    #---------------------------------------------------------------#
    
    #---------------------------------------------------------------#
    # BEGIN: KERLExtensions Implementation                          #
    #---------------------------------------------------------------#

   

    def getDependencies(self, expression):
        """
            Returns a list of components that are required to
            evaluate the component class specific KERL expression.

            NOTE: Includes the specific component itself.

            RETURN TYPE: {Component} indexed by Component.getIdentity()
       """

        return {self.getIdentity():self}
    

    #---------------------------------------------------------------#
    
    def getDisplayIncoming(self):
        """ Should this component display incoming links? """
        
        return getattr(self.aq_explicit, 'displayIncoming', False)

    #---------------------------------------------------------------#

    def getDisplayOutgoing(self):
        """ Should this component display outgoing links? """
        
        return getattr(self.aq_explicit, 'displayOutgoing', False)

    #---------------------------------------------------------------#
    
    def getDisplayFields(self):
        """ Return a list of component identities to display in the results table """
        
        vocab = []
        
        rawData = getattr(self.aq_explicit, "displayFields", "").split("\n")
        for row in rawData:
            if not row.strip(): continue
            
            if "|" in row:
                key, value = row.split("|")
                key, value = key.strip(), value.strip()
            else:
                key = row.strip()
                value = key
                
            componentIdentities = key.split(",")
            
            vocab.append(( componentIdentities, value ))
            
        return vocab
        #return filter(None, [value.strip() for value in getattr(self.aq_explicit, "displayFields", '').split("\n")])
    
    #---------------------------------------------------------------#
    
    def getShowInReport(self):
        """ Should this component be shown on reports? """
        
        return getattr(self, 'showInReport', False)
    
    #---------------------------------------------------------------#
    
    def getShowInAssessment(self):
        """ Should this component be shown on assessments? """
        
        return getattr(self, 'showInAssessment', False)
   

    #---------------------------------------------------------------#
   
    def getReportContent(self, *args, **kwargs):
        """ Fakes some report content so this field always displays """
        
        return "-"
   
    #---------------------------------------------------------------#
    
    def getShowModel(self):
        """ Show model """
        
        return getattr(self.aq_explicit, "showModel", False)
    
    #---------------------------------------------------------------#
    
    def getShowDate(self):
        """ Show model """
        
        return getattr(self.aq_explicit, "showDate", False)
   
    #---------------------------------------------------------------#
    
    def getShowAuthor(self):
        """ Show model """
        
        return getattr(self.aq_explicit, "showAuthor", False)
   
    #---------------------------------------------------------------#
    
    def getShowReports(self):
        """ Show model """
        
        return getattr(self.aq_explicit, "showReports", False)
   
    #---------------------------------------------------------------#    

#####################################################################
## Class Initialisation

# Register Component Information with the Knowledge Engine
registerGenericObjectClass(LinkReport)

#####################################################################
